package com.stars.util.common;

import com.alibaba.fastjson2.JSON;
import com.github.f4b6a3.ulid.UlidCreator;
import com.stars.base.constants.RedisConstants;
import com.stars.base.entity.BaseEntity;
import com.stars.base.entity.SessionUser;
import com.stars.config.DBConfig;
import com.stars.util.cache.CacheUtil;
import com.stars.util.context.SpringContextUtil;
import com.stars.util.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author : Rocks
 * @version : 1.0
 * @date : 2022/10/1 23:29
 * @description : 开发工具包
 */
@Slf4j
public class DevelopKit {

    private static final CacheUtil cacheUtil;

    static {
        cacheUtil = SpringContextUtil.getBean(CacheUtil.class);
    }

    /**
     * 生成主键
     * @author : Rocks
     * @date :  2022/10/1 23:32
     * @return String
     */
    public static String generateUUID(){
        return UlidCreator.getUlid().toString();
    }

    /**
     * 继承BaseEntity实体Bean，公共字段赋值
     * @author : Rocks
     * @date :  2023/2/25 23:20
     * @param entity 实体Bean
     */
    public static void setBaseInfo(BaseEntity entity) {
        SessionUser user = getSessionUser();
        setBaseInfo(entity, user);
    }

    public static void setBaseInfo(BaseEntity entity, SessionUser user) {
        entity.setCreateDate(new Date());
        entity.setRowStatus(1);
        entity.setLastUpdateTime(new Date());
        if(user!=null){
            entity.setCreateUserId(user.getUserId());
            entity.setCreateUserName(user.getUserName());
            entity.setCreateDeptId(user.getCurrentDept());
            entity.setCreateDeptName(user.getCurrentDeptName());
            entity.setCreateUnitId(user.getCurrentUnit());
            entity.setCreateUnitName(user.getCurrentUnitName());
        }
    }

    /**
     * 获取当前请求的SessionUser
     * @author : Rocks
     * @date :  2023/2/25 23:22
     * @return SessionUser 返回当前登录用户对象
     */
    public static SessionUser getSessionUser(){

        Object principal = SecurityUtils.getSubject().getPrincipal();

        if (principal != null) {
            return cacheUtil.getValue(false,RedisConstants.SESSION_PREFIX + principal , SessionUser.class);
        }

        HttpServletRequest request = getRequest();
        if(request != null){
            return getSessionUser(request);
        }

        return null;
    }

    /**
     * 获取当前请求的SessionUser
     * @author : Rocks
     * @date :  2023/7/25 21:17
     * @param request request
     * @return SessionUser 返回当前登录用户对象
     */
    public static SessionUser getSessionUser (HttpServletRequest request) {

        String auth = request.getHeader("Authorization");

        String sessionId = JWTUtil.getClaim(auth, "sessionId");

        if (StringUtils.hasLength(sessionId)) {
            return cacheUtil.getValue(false,RedisConstants.SESSION_PREFIX + sessionId, SessionUser.class);
        }

        return null;
    }

    public static HttpServletRequest getRequest() {
        HttpServletRequest request = null;

        try {
            request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        } catch (Exception e) {
            log.error("获取request异常",e);
        }

        return request;
    }

    /**
     * 将Object对象转换成Class链表
     * @author : Rocks
     * @date :  2023/2/25 23:22
     * @param obj 要转换的数据
     * @param clazz 要转换成Class
     * @return List<T> 转换成实体Bean的list
     */
    public static <T> List<T> castObj2List(Object obj,Class<T> clazz) {
        if(!(obj instanceof List<?>)) {
            return null;
        }
        List<T> result = new ArrayList<>();
        for(Object o : (List<?>)obj) {
            result.add(JSON.to(clazz,o));
        }
        return result;
    }

    public static String getStringFromDBConfig(String key) {
        return getStringFromDBConfig(key, "");
    }

    public static String getStringFromDBConfig(String key, String defaultValue) {
        SessionUser user = getSessionUser();
        String configValue = DBConfig.getString(key, user);
        if (!StringUtils.hasLength(configValue)) {
            configValue = defaultValue;
        }

        return configValue;
    }
}
